package com.cz.ssyx.cart.service.impl;

import com.cz.ssyx.cart.service.CartInfoService;
import com.cz.ssyx.client.product.ProductFeignClient;
import com.cz.ssyx.common.constant.RedisConst;
import com.cz.ssyx.common.exception.MyException;
import com.cz.ssyx.common.result.ResultCodeEnum;
import com.cz.ssyx.enums.SkuType;
import com.cz.ssyx.model.order.CartInfo;
import com.cz.ssyx.model.product.SkuInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @descriptions:
 * @author: Joker.
 * @date: 2024/5/1 17:34
 * @version: 1.0
 */

@Service
public class CartInfoServiceImpl implements CartInfoService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private ProductFeignClient productFeignClient;

    //添加商品到购物车
    @Override
    public void addToCart(Long userId, Long skuId, Integer skuNum) {

        String cartKey = this.getCartKey(userId);

        //1.根据key = userId查询购物车信息
        BoundHashOperations<String, String, CartInfo> hashOperations =
                                            redisTemplate.boundHashOps(cartKey);

        CartInfo cartInfo = null;
        //2.判断该用户的购物车中的商品是否已经存在
        if (hashOperations.hasKey(skuId.toString())) {
            //如果有该商品
            cartInfo = hashOperations.get(skuId.toString());
            //现在的商品数量
            Integer currentSkuNum = cartInfo.getSkuNum() + skuNum;

            if (currentSkuNum < 1) {
                return;
            }
            //设置当前数量
            cartInfo.setSkuNum(currentSkuNum);
            cartInfo.setCurrentBuyNum(currentSkuNum);

            //判断是否大于限购数量
            if (currentSkuNum > cartInfo.getPerLimit()) {
                throw new MyException(ResultCodeEnum.SKU_LIMIT_ERROR);
            }

            //设置选中状态
            cartInfo.setIsChecked(1);
            cartInfo.setUpdateTime(new Date());
            hashOperations.put(skuId.toString(), cartInfo);
        }else {
            //没有该商品  第一次加入该商品
            skuNum = 1;

            //远程调用商品的信息
            SkuInfo skuInfo = productFeignClient.getSkuInfoById(skuId);

            if (skuInfo == null) {
                throw new MyException(ResultCodeEnum.DATA_ERROR);
            }
            //封装到购物车
            cartInfo = new CartInfo();
            cartInfo.setSkuId(skuId);
            cartInfo.setCategoryId(skuInfo.getCategoryId());
            cartInfo.setSkuType(skuInfo.getSkuType());
            cartInfo.setIsNewPerson(skuInfo.getIsNewPerson());
            cartInfo.setUserId(userId);
            cartInfo.setCartPrice(skuInfo.getPrice());
            cartInfo.setSkuNum(skuNum);
            cartInfo.setCurrentBuyNum(skuNum);
            cartInfo.setSkuType(SkuType.COMMON.getCode());
            cartInfo.setPerLimit(skuInfo.getPerLimit());
            cartInfo.setImgUrl(skuInfo.getImgUrl());
            cartInfo.setSkuName(skuInfo.getSkuName());
            cartInfo.setWareId(skuInfo.getWareId());
            cartInfo.setIsChecked(1);
            cartInfo.setStatus(1);
            cartInfo.setCreateTime(new Date());
            cartInfo.setUpdateTime(new Date());

            //更新缓存
            hashOperations.put(skuId.toString(), cartInfo);
            //设置过期时间
            this.setCartKeyExpire(cartKey);
        }
    }

    //根据skuId删除购物车
    @Override
    public void deleteCart(Long userId, Long skuId) {
        BoundHashOperations<String, String, CartInfo> hashOperations = redisTemplate.boundHashOps(this.getCartKey(userId));
        if (hashOperations.hasKey(skuId.toString())) {
            hashOperations.delete(skuId.toString());
        }
    }

    //清空购物车
    @Override
    public void deleteAllCart(Long userId) {
        BoundHashOperations<String, String, CartInfo> hashOperations = redisTemplate.boundHashOps(this.getCartKey(userId));
        List<CartInfo> cartInfoList = hashOperations.values();
        if (cartInfoList != null) {
            for (CartInfo cartInfo : cartInfoList) {
                hashOperations.delete(cartInfo.getSkuId().toString());
            }
        }
    }

    //批量删除购物车
    @Override
    public void batchDeleteCart(Long userId, List<Long> skuIdList) {
        BoundHashOperations<String, String, CartInfo> hashOperations = redisTemplate.boundHashOps(this.getCartKey(userId));
        for (Long skuId : skuIdList) {
            if (hashOperations.hasKey(skuId)){
                hashOperations.delete(skuId);
            }
        }
    }

    //购物车列表
    @Override
    public List<CartInfo> cartList(Long userId) {

        List<CartInfo> cartInfoList = new ArrayList<>();

        if (StringUtils.isEmpty(userId)) {
            return cartInfoList;
        }
        //获得购物车数据
        BoundHashOperations<String, String, CartInfo> hashOperations = redisTemplate.boundHashOps(this.getCartKey(userId));
        cartInfoList = hashOperations.values();

        //按商品加入购物车的时间排序
        if (!CollectionUtils.isEmpty(cartInfoList)) {
            cartInfoList.sort(new Comparator<CartInfo>() {
                @Override
                public int compare(CartInfo o1, CartInfo o2) {
                    return o1.getCreateTime().compareTo(o2.getCreateTime());
                }
            });
        }
        return cartInfoList;
    }

    //根据skuId设置购物车商品是否选中
    @Override
    public void checkCartBySkuId(Long userId, Long skuId, Integer isCheck) {
        //先根据userId获取该用户的购物车信息
        BoundHashOperations<String, String, CartInfo> hashOperations = redisTemplate.boundHashOps(this.getCartKey(userId));
        CartInfo cartInfo = hashOperations.get(skuId.toString());
        if (cartInfo != null) {
            cartInfo.setIsChecked(isCheck);
            //更新
            hashOperations.put(skuId.toString(), cartInfo);
            //设置key过期时间
            this.setCartKeyExpire(this.getCartKey(userId));
        }
    }

    //全选
    @Override
    public void checkAllCart(Long userId, Integer isCheck) {
        String cartKey = this.getCartKey(userId);
        BoundHashOperations<String, String, CartInfo> hashOperations = redisTemplate.boundHashOps(cartKey);
        //得到所有购物商品项
        List<CartInfo> cartInfoList = hashOperations.values();
        cartInfoList.forEach(cartInfo -> {
            //遍历
            cartInfo.setIsChecked(isCheck);
            hashOperations.put(cartInfo.getSkuId().toString(), cartInfo);
        });
        this.setCartKeyExpire(cartKey);
    }

    //批量选中
    @Override
    public void batchCartCheck(Long userId, List<Long> skuIdList, Integer isCheck) {
        String cartKey = this.getCartKey(userId);
        BoundHashOperations<String, String, CartInfo> hashOperations = redisTemplate.boundHashOps(cartKey);
        skuIdList.forEach(skuId -> {
            CartInfo cartInfo = hashOperations.get(skuId.toString());
            cartInfo.setIsChecked(isCheck);
            hashOperations.put(skuId.toString(), cartInfo);
        });
        this.setCartKeyExpire(cartKey);
    }

    //获取购物车中选中的商品列表
    @Override
    public List<CartInfo> getCartCheckedList(Long userId) {
        List<CartInfo> cartInfoList = null;
        BoundHashOperations<String, String, CartInfo> hashOperations = redisTemplate.boundHashOps(this.getCartKey(userId));
        List<CartInfo> allCartInfoList = hashOperations.values();
//        allCartInfoList.forEach(cartInfo -> {
//            if (cartInfo.getIsChecked() == 1){
//                cartInfoList.add(cartInfo);
//            }
//        });
        cartInfoList = allCartInfoList.stream().filter(cartInfo -> cartInfo.getIsChecked().intValue() == 1).collect(Collectors.toList());
        return cartInfoList;
    }

    //删除购物车选中的商品
    @Override
    public void deleteCartChecked(Long userId) {
        //根据userId查询出购物车记录
        List<CartInfo> cartCheckedList = this.getCartCheckedList(userId);

        //得到skuIdList
        List<Long> skuIdList = cartCheckedList.stream().map(CartInfo::getSkuId).collect(Collectors.toList());

        BoundHashOperations<String, String, CartInfo> hashOperations = redisTemplate.boundHashOps(this.getCartKey(userId));
        //hashOperations.delete(skuIdList.toString());  //TODO 测试这里是否可以删除一个集合
        skuIdList.forEach(skuId -> hashOperations.delete(skuId.toString()));
    }

    //定义一个方法根据user：+ userId + cart 拼接一个key
    public String getCartKey(Long userId) {
        return RedisConst.USER_KEY_PREFIX + userId + RedisConst.USER_CART_KEY_SUFFIX;
    }

    //  设置key 的过期时间！
    private void setCartKeyExpire(String cartKey) {
        redisTemplate.expire(cartKey, RedisConst.USER_CART_EXPIRE, TimeUnit.SECONDS);
    }
}
